﻿using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Core;
using Serilog.Events;

namespace Apps.Extensions.Logger;

/// <summary>
/// 日志工具
/// </summary>
public static class SeriLogUtil
{
    static string LogFilePath(string LogEvent) =>
        $@"{AppDomain.CurrentDomain.BaseDirectory}/AppLogs/{LogEvent}/{LogEvent}_.log";

    /// <summary>
    /// 启动
    /// </summary>
    /// <param name="builder"></param>
    /// <returns></returns>
    public static WebApplicationBuilder AddLogUtil(this WebApplicationBuilder builder)
    {

        var configuration = new ConfigurationBuilder()
    .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .Build();

        Serilog.Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
            .ReadFrom.Configuration(configuration)
            .Enrich.FromLogContext()
            .Enrich.With(new DateTimeNowEnricher())
            .Enrich.With(new ThreadIdEnricher())  //增加自定义配置
            .WriteTo.Console()
            .Enrich.FromLogContext()
            .CreateLogger();

        #region  代码配置，可以完全区分日志级别
        //var fileMaxSize = 1 * 1024 * 1024 * 10;
        //var logger = new LoggerConfiguration()
        //    .Enrich.With(new DateTimeNowEnricher())
        //    .Enrich.FromLogContext()//记录相关上下文信息
        //    .MinimumLevel.Information()//最小记录级别
        //    .MinimumLevel.Override(nameof(Microsoft), LogEventLevel.Error)//对其他日志进行重写,除此之外,目前框架只有微软自带的日志组件
        //    .WriteTo
        //        .File(
        //            LogFilePath("All"),
        //            LogEventLevel.Information,
        //            rollingInterval: RollingInterval.Day,
        //            rollOnFileSizeLimit: true,
        //            fileSizeLimitBytes: fileMaxSize
        //        )
        //    .WriteTo.Console();

        //if (builder.Environment.IsDevelopment())
        //{
        //    logger.WriteTo.Console(LogEventLevel.Error);//控制台输出
        //}

        //Serilog.Log.Logger = logger
        //.WriteTo.Logger(lg =>
        //{
        //    lg.Filter
        //    .ByIncludingOnly(p => p.Level == LogEventLevel.Debug)
        //    .WriteTo.File(LogFilePath(nameof(LogEventLevel.Debug)), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: fileMaxSize);
        //})
        //.WriteTo.Logger(lg =>
        //{
        //    lg.Filter
        //    .ByIncludingOnly(p => p.Level == LogEventLevel.Information)
        //    .WriteTo.File(LogFilePath(nameof(LogEventLevel.Information)), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: fileMaxSize);
        //})
        //.WriteTo.Logger(lg =>
        //{
        //    lg.Filter
        //    .ByIncludingOnly(p => p.Level == LogEventLevel.Warning)
        //    .WriteTo.File(LogFilePath(nameof(LogEventLevel.Warning)), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: fileMaxSize);
        //})
        //.WriteTo.Logger(lg =>
        //{
        //    lg.Filter
        //    .ByIncludingOnly(p => p.Level == LogEventLevel.Error)
        //    .WriteTo.File(LogFilePath(nameof(LogEventLevel.Error)), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: fileMaxSize);
        //})
        //.WriteTo.Logger(lg =>
        //{
        //    lg.Filter
        //    .ByIncludingOnly(p => p.Level == LogEventLevel.Fatal)
        //    .WriteTo.File(LogFilePath(nameof(LogEventLevel.Fatal)), rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: fileMaxSize);
        //})
        //.CreateLogger();
        #endregion
        // log 日志配置
        builder.Host.UseSerilog();
        return builder;
    }

}

/// <summary>
/// 时间处理
/// </summary>
class DateTimeNowEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
            "DateTimeNow", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
    }
}
public class ThreadIdEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
                "ThreadId", Environment.CurrentManagedThreadId));
    }
}